package com.example.admin.smstest.sms;

import android.app.Activity;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 在短信中获取 验证码
 * Created by admin on 2017/6/9.
 */

public class SmsCodeObserver extends ContentObserver {

    private Activity mActivity;
    private static final String TAG = SmsCodeObserver.class.getSimpleName();
    private static final String MARKER = "YOUR_KEYWORD";
    private Cursor cursor = null;

    public SmsCodeObserver(Activity activity, Handler handler) {
        super(handler);
        this.mActivity = activity;
    }

    public void onChange (boolean selfChange) {
        super.onChange(selfChange);
        onChange(selfChange, null);
    }

    @Override
    public void onChange(boolean selfChange, Uri uri) {

        /**
         * 适配某些较旧的设备，可能只会触发onChange(boolean selfChange)方法，没有传回uri参数，
         * 此时只能通过"content://sms/inbox"来查询短信
         */
        if (uri == null) {
            uri = Uri.parse("content://sms/inbox");
        }

        if (uri.toString().equals("content://sms/raw")) {
            return;
        }
        cursor = this.mActivity.getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            if (cursor.moveToFirst()) {
                int id = cursor.getInt(cursor.getColumnIndex("_id"));
                String body = cursor.getString(cursor.getColumnIndex("body"));
                Log.d(TAG, "sms id: " + id + "\nsms body: " + body);
                cursor.close();
                // Already got sms body, do anything you want, for example: filter the verify code
                getVerifyCode(body);
            }
        }
        else {
            Log.e(TAG, "error: cursor == null");
        }
    }

    /**
     * 注册一个更改sms的监视器
     */
    public void register() {
        Log.d(TAG, "Register sms monitor");
        this.mActivity.getContentResolver().registerContentObserver(
                Uri.parse("content://sms/"), true, this);
    }

    /**
     * 取消对sms更改的监视器
     */
    public void unRegister() {
        Log.d(TAG, "Unregister sms monitor");
        this.mActivity.getContentResolver().unregisterContentObserver(this);
    }

    /**
     * 从sms主体获得验证码
     * @param str
     * @return
     */
    public String getVerifyCode(String str) {
        String verifyCode = null;
        if (smsContentFilter(str)) {
            Log.d(TAG, "sms content matched, auto-fill verify code.");
            verifyCode = getDynamicPassword(str);
        }
        else {
            // Do nothing
            Log.d(TAG, "sms content did not match, do nothing.");
        }
        return verifyCode;
    }

    /**
     * 检查是否 str 是验证代码格式化
     *
     * @param str
     * @return
     */
    private boolean smsContentFilter(String str) {
        Log.d(TAG, "smsContentFilter. smsBody = " + str);
        boolean isMatched = false;
        if (!TextUtils.isEmpty(str)) {
            // Check if str contains keyword
            if (str.contains(MARKER)) {
                Log.d(TAG, "This sms contains \"" + MARKER + "\"");
                // Check if str contains continuous 6 numbers
                Pattern  continuousNumberPattern = Pattern.compile("[0-9\\.]+");
                Matcher m = continuousNumberPattern.matcher(str);
                while(m.find()){
                    if(m.group().length() == 6) {
                        Log.d(TAG, "This sms contains continuous 6 numbers : " + m.group());
                        isMatched = true;
                    }
                }
            }
        }
        return isMatched;
    }

    /**
     * 从str中剪切连续的6个数字
     *
     * @param str sms content
     * @return verification code
     */
    private String getDynamicPassword(String str) {
        Log.d(TAG, "getDynamicPassword. smsBody = " + str);
        Pattern continuousNumberPattern = Pattern.compile("[0-9\\.]+");
        Matcher m = continuousNumberPattern.matcher(str);
        String dynamicPassword = "";
        while(m.find()){
            if(m.group().length() == 6) {
                Log.d(TAG, m.group());
                dynamicPassword = m.group();
            }
        }
        Log.d(TAG, "Verification code: " + dynamicPassword);
        return dynamicPassword;
    }

}
